﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Chefbook.HelperMethods;
using System.Collections.ObjectModel;

namespace Chefbook.DataAccessLayer
{
    public partial class Category
    {
        public Category()
        {
            _Name = string.Empty;
            
        }

        /// <summary>
        /// Removes all links from this category
        /// </summary>
        public void Delete()
        {
            foreach (var recipe in recipes)
            {
                recipes.Remove(recipe);
            }
            Parent = null;
        }

        /// <summary>
        /// Adds a category as a sub of this category
        /// </summary>
        /// <param name="subToAdd">The category to add as a sub</param>
        public void AddSubcategory(Category subToAdd)
        {
            subToAdd.ThrowIfNull("subToAdd");
            subcategories.Add(subToAdd);
        }

        /// <summary>
        /// Removes a sub from this category
        /// </summary>
        /// <param name="categoryToRemove">The sub to remove</param>
        public void RemoveSubcategory(Category categoryToRemove)
        {
            categoryToRemove.ThrowIfNull("recipeToRemove");
            ParameterValidation.ValidateArgument(() => this.subcategories.Contains(categoryToRemove), "recipeToRemove");
            subcategories.Remove(categoryToRemove);
        }

        /// <summary>
        /// Adds a recipe to this category's direct recipes
        /// </summary>
        /// <param name="recipeToAdd">The recipe to add</param>
        public void AddRecipe(Recipe recipeToAdd)
        {
            recipeToAdd.ThrowIfNull("recipeToAdd");
            recipes.Add(recipeToAdd);
        }

        /// <summary>
        /// Removes a recipe from this category
        /// </summary>
        /// <param name="recipeToRemove">The recipe to remove</param>
        public void RemoveRecipe(Recipe recipeToRemove)
        {
            recipeToRemove.ThrowIfNull("recipeToRemove");
            ParameterValidation.ValidateArgument(() => this.recipes.Contains(recipeToRemove), "recipeToRemove");
            recipes.Remove(recipeToRemove);
        }

        /// <summary>
        /// Gets a readonlylist of direct subcategories of this category
        /// </summary>
        public ReadOnlyCollection<Category> Subcategories
        {
            get { return subcategories.ToList().AsReadOnly(); }
        }

        /// <summary>
        /// Gets a readonly list of recipes contained directly in this category 
        /// not one of its subcategories
        /// </summary>
        public ReadOnlyCollection<Recipe> DirectRecipes
        {
            get { return recipes.ToList().AsReadOnly(); }
        }

        /// <summary>
        /// Gets readonly list of all recipes contained in this category or one of its subcategories
        /// </summary>
        public ReadOnlyCollection<Recipe> AllRecipes
        {
            get 
            {
                List<Recipe> allrecipes = new List<Recipe>(DirectRecipes);
                foreach (var sub in Subcategories)
                {
                    allrecipes.AddRange(sub.AllRecipes);
                }
                return allrecipes.AsReadOnly(); 
            }
        }

    }
}
